import React, { PureComponent } from 'react';
import { connect } from 'dva';
import { Form } from '@ant-design/compatible';
import '@ant-design/compatible/assets/index.css';
import { Button, Input, Modal, Select, DatePicker, Radio, InputNumber, message } from 'antd';
import { transferOption } from '@/support/utils';
import PateoFileUpload from '../PateoFileUpload';

/**
 *    input  radio  datePicker  inputNumber  textArea  select
 *    todo  图片上传img  文件上传file  富文本编辑器（预留后期实现）
 *          树选择  级联选择  时间段选择  开关switch
 *
 *    数据回显方法由自己自定义实现，默认不做处理
 */

const FormItem = Form.Item;
const RadioGroup = Radio.Group;
const { TextArea } = Input;
export const itemLayout = {
  labelCol: {
    xs: { span: 24 },
    sm: { span: 6 },
  },
  wrapperCol: {
    xs: { span: 24 },
    sm: { span: 14 },
  },
};

@connect()
@Form.create({
  mapPropsToFields(props) {
    const formDataEdit = Object.assign({}, props.formData);
    if (props.createFormField) {
      return props.createFormField(formDataEdit);
    } else {
      for (const i in formDataEdit) {
        formDataEdit[i] = Form.createFormField({ value: formDataEdit[i] });
      }
      return formDataEdit;
    }
  },
})
export default class PateoModalForm extends PureComponent<any, any> {
  state = {
    loading: false, // 按钮的loading(不使用props中loading是因为会触发mapPropsToFields导致重新赋值)
  };

  handleSubmit = e => {
    e.preventDefault();
    const { form: { validateFields }, postUrl, handleModalFieldsValue,handleCallback, customValidator, formData,messageInfo=["新增成功","编辑成功"], dispatch } = this.props;
    validateFields((err, fieldsValue) => {
      if (err) return;

      //  自定义校验规则
      if (customValidator && customValidator.length > 0) {
        let status = true;
        let tempMsg = ''
        customValidator.some((item: any) => {
          let state = item.validator()
          if (!state) {
            status = state
            tempMsg = item.msg
          }
          return !state
        })
        if (!status) {
          message.error(tempMsg)
          return
        }
      }

      // 自定义数据处理方法。必须return处理之后的数据才会提交，否则不提交
      const values = handleModalFieldsValue
        ? handleModalFieldsValue(fieldsValue)
        : { ...fieldsValue };
      if (!values) return;

      // 数据为空处理
      for (let v in values) {
        if ((values[v] != 0 && !values[v]) || !values[v].toString().trim()) {
          values[v] = undefined;
        }
      }

      // 组合formData以及当前表单的值  解构赋值不改变原对象
      const pushData = { ...formData, ...values };
      this.setState({ loading: true });
      dispatch({
        type: 'extend/commonPost',
        payload: { url: postUrl, ...pushData },
        callback: response => {
          if (response.statusCode === '0') {
            message.success(formData.id || formData.sid ? messageInfo[1] : messageInfo[0]);
            this.handleCancel();
            this.setState({ loading: false });
            // 重新查询列表区分是否属于新增，编辑
            if (handleCallback) handleCallback(formData.id || formData.sid ? true : undefined);
          } else {
            this.setState({ loading: false });
          }
        },
      });
    });
  };

  handleCancel = () => {
    const {
      form: { resetFields },
      changeVisible,
    } = this.props;
    changeVisible();
    resetFields();
  };

  renderFormItem = () => {
    const { form: { getFieldDecorator,setFieldsValue,getFieldValue }, formItems, formData, formItemLayout = itemLayout } = this.props;
    const loopFormItems = data => data.map((item) => {
      const { key, type, rules = [], initialValue, editDisabled } = item;
      // 编辑禁用属性
      const disabled = editDisabled && (!!formData.id || !!formData.sid);
      const options = {
        rules,
        initialValue,
      };
      const componentDecorator = getFieldDecorator(key, options);
      switch (type) {
        case 'input': {
          const { title, key, type, rules = [], initialValue, editDisabled, maxLength, ...rest } = item;
          const placeholder = `请输入${typeof (title) === 'string' ? title : ''}`;
          return (
              <FormItem
                key={key}
                label={title}
                {...formItemLayout}
              >
                {
                  componentDecorator(
                    <Input
                      placeholder={placeholder}
                      disabled={disabled}
                      maxLength={maxLength}
                      {...rest}
                    />
                  )
                }
              </FormItem>);
        }
        case 'radio': {
          const { title, key, type, rules = [], initialValue, editDisabled, options, onChange, ...rest } = item;
          return (
              <FormItem
                key={key}
                label={title}
                {...formItemLayout}
              >
                {
                  componentDecorator(
                  <RadioGroup
                    options={options}
                    disabled={disabled}
                    onChange={onChange}
                    {...rest}
                  />,
                )}
              </FormItem>
            );
          }
          case 'radio': {
            const {
              title,
              key,
              type,
              rules = [],
              initialValue,
              editDisabled,
              options,
              ...rest
            } = item;
            return (
              <FormItem key={key} label={title} {...formItemLayout}>
                {componentDecorator(<RadioGroup options={options} disabled={disabled} {...rest} />)}
              </FormItem>
            );
          }
          case 'datePicker': {
            const {
              title,
              key,
              type,
              rules = [],
              initialValue,
              editDisabled,
              format = 'YYYY-MM-DD',
              showTime = false,
              style,
              ...rest
            } = item;
            return (
              <FormItem key={key} label={title} {...formItemLayout}>
                {componentDecorator(
                  <DatePicker
                    allowClear
                    placeholder="请选择"
                    showTime={showTime}
                    disabled={disabled}
                    showToday
                    format={format}
                    style={{ width: '100%', ...style }}
                    getCalendarContainer={trigger => trigger.parentNode}
                    {...rest}
                  />,
                )}
              </FormItem>
            );
          }
          case 'inputNumber': {
            const {
              title,
              key,
              type,
              rules = [],
              initialValue,
              editDisabled,
              style,
              ...rest
            } = item;
            return (
              <FormItem key={key} label={title} {...formItemLayout}>
                {componentDecorator(
                  <InputNumber
                    allowClear
                    placeholder="请输入"
                    disabled={disabled}
                    style={{ width: '100%', ...style }}
                    {...rest}
                  />,
                )}
              </FormItem>
            );
          }
          case 'textArea': {
            const {
              title,
              key,
              type,
              rules = [],
              initialValue,
              editDisabled,
              rows = 4,
              maxLength,
              ...rest
            } = item;
            const placeholder = `请输入${typeof title === 'string' ? title : ''}`;
            return (
              <FormItem key={key} label={title} {...formItemLayout}>
                {componentDecorator(
                  <TextArea
                    placeholder={placeholder}
                    rows={rows}
                    disabled={disabled}
                    maxLength={maxLength}
                    {...rest}
                  />,
                )}
              </FormItem>
            );
          }
          case 'select': {
            const {
              title,
              key,
              type,
              rules = [],
              initialValue,
              editDisabled,
              selectOptions = [],
              keyValue = ['value', 'label'],
              onSelectChange,
              showSearch = false,
              ...rest
            } = item;
            const extra = showSearch
              ? {
                  showSearch: true,
                  optionFilterProp: 'children',
                }
              : {};
            return (
              <FormItem key={key} label={title} {...formItemLayout}>
                {componentDecorator(
                  <Select
                    placeholder="请选择"
                    allowClear
                    onChange={onSelectChange}
                    disabled={disabled}
                    getPopupContainer={triggerNode => triggerNode.parentNode}
                    {...extra}
                    {...rest}
                  >
                    {transferOption(selectOptions, keyValue)}
                  </Select>,
                )}
              </FormItem>
            );
          }
          case 'file': {
            const {
              title,
              key,
              type,
              rules = [],
              initialValue,
              editDisabled,
              listType,
              fileMaxSize = 10,
              suffix = '',
              uploadUrl = '/common/upload/all',
              tag = 'button',
              text = '上传',
              ...rest
            } = item;
            return (
              <FormItem key={key} label={title} {...formItemLayout}>
                {componentDecorator(
                  <PateoFileUpload
                    uploadSuccess={url => setFieldsValue({ [key]: url })}
                    fileUrl={getFieldValue(key)}
                    // 以下是自定义属性，默认不需要
                    fileMaxSize={fileMaxSize}
                    suffix={suffix}
                    uploadUrl={uploadUrl}
                    tag={tag}
                    text={text}
                    listType={listType}
                    {...rest}
                  />,
                )}
              </FormItem>
            );
          }
          case 'custom': {
            if (item.item instanceof Function) {
              return item.item();
            }
            return null;
          }
        }
      });
    return loopFormItems(formItems);
  };

  render() {
    const {
      formData,
      visible,
      width,
      style,
      title = ['新增', '编辑'],
      buttonName = ['保 存', '取 消'],
      ...rest
    } = this.props;
    const { loading } = this.state;
    return (
      <Modal
        width={width || 520}
        wrapClassName="wrapModel"
        visible={visible}
        style={{ ...style }}
        title={formData.id || formData.sid ? title[1] : title[0]}
        closable
        {...rest}
        onCancel={this.handleCancel}
        footer={[
          <Button key="back" type="ghost" size="small" onClick={this.handleCancel}>
            {buttonName[1]}
          </Button>,
          <Button
            key="submit"
            type="primary"
            size="small"
            loading={loading}
            onClick={this.handleSubmit}
          >
            {buttonName[0]}
          </Button>,
        ]}
      >
        <Form>{this.renderFormItem()}</Form>
      </Modal>
    );
  }
}
